﻿using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ShanNiang.Hosting;
using ShanNiang.Hosting.Extensions;
using ShanNiang.Service;
using ShanNiang.Service.Attributes;
using ShanNiang.Service.Constants;
using ShanNiang.Service.Interfaces;
using ShanNiang.Service.LoginModels.Responses;
using ShanNiang.Service.PackingModels.Requests;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Security.AccessControl;
using System.Windows;
using System.Windows.Threading;

namespace ShanNiang.Mvvm.ViewModels
{
    /// <summary>
    /// 主窗体视图数据
    /// </summary>
    public partial class MainWindowViewModel : UIViewModel, IRecipient<PropertyChangedMessage<bool>>
    {
        private readonly IServiceProvider _services;
        private readonly UserContext _userContext;
        private readonly IXkmService _xkmService;
        private readonly Dispatcher _dispatcher;
        private readonly PackingConfig _packingConfig;
        private readonly string DataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CommonData.DataFolder);
        /// <summary>
        /// 全部菜单
        /// </summary>
        private readonly Dictionary<string, MenuViewModel> _allMenus;


        public MainWindowViewModel(
            IServiceProvider services,
            UserContext userContext,
            IXkmService xkmService,
            Dispatcher dispatcher,
            PackingConfig packingConfig,
            IMapper mapper, ILogger<MainWindowViewModel> logger) : base(mapper, logger)
        {
            _services = services;
            _allMenus = new Dictionary<string, MenuViewModel>();
            _userContext = userContext;
            _xkmService = xkmService;
            _dispatcher = dispatcher;
            _packingConfig = packingConfig;
            User = new UserViewModel();
            FullScreen = packingConfig.FullScreen;
            Version = typeof(MainWindowViewModel).Assembly.GetName().Version;
            if (!Directory.Exists(DataFolder))
            {
                Directory.CreateDirectory(DataFolder);
            }
        }
        #region 可绑定属性
        /// <summary>
        /// 全屏
        /// </summary>
        [ObservableProperty]
        private bool _fullScreen;
        /// <summary>
        /// 已选择的菜单
        /// </summary>
        [ObservableProperty]
        private MenuViewModel? _selectedMenu;
        /// <summary>
        /// 10次
        /// </summary>
        [ObservableProperty]
        private int _tenTimes;
        /// <summary>
        /// 当前用户
        /// </summary>
        [ObservableProperty]
        private UserViewModel _user;
        /// <summary>
        /// 当前版本
        /// </summary>
        [ObservableProperty]
        private Version? _version;
        #endregion

        /// <summary>
        /// 添加现有的用户控件
        /// </summary>
        /// <param name="userControl"></param>
        public void AddMenuViewModel(string menuCode, MenuViewModel userControl)
        {
            _allMenus[menuCode] = userControl;
        }
        /// <summary>
        /// 清除已缓存的用户控件
        /// </summary>
        public void ClearMenuViewModels()
        {
            _allMenus.Clear();
        }
        /// <summary>
        /// 收到消息
        /// </summary>
        /// <param name="message"></param>
        public void Receive(PropertyChangedMessage<bool> message)
        {
            if (message != null && message.PropertyName == CommonData.GotToken && message.NewValue)
            {
                LoadedCommand.Execute(null);
                IsActive = false;
            }
        }

        #region 可绑定commmand
        /// <summary>
        /// 关闭后事件处理
        /// </summary>
        [RelayCommand]
        private void Closed()
        {
            if (_packingConfig.CloseWindows)
            {
                ProcessStartInfo cancelPsi = new ProcessStartInfo("shutdown", "-s");
                cancelPsi.Verb = "runas"; // 需要管理员权限
                Process.Start(cancelPsi);
            }
        }
        /// <summary>
        /// 关闭前事件处理
        /// </summary>
        [RelayCommand]
        private void Closing()
        {
            //保存数据到缓存
            var types = typeof(MainWindowViewModel).Assembly.GetTypes().Where(t => IsInheriteFrom(t, typeof(UIViewModel))).ToArray();
            if (types != null && types.Length > 0)
            {
                foreach (var type in types)
                {
                    var instance = _services.GetService(type);
                    if (instance != null)
                    {
                        var viewModel = (UIViewModel)instance;
                        viewModel.SaveData();
                    }
                }
            }
        }
        /// <summary>
        /// 加载用户基本信息
        /// </summary>
        [RelayCommand]
        private async Task LoadedAsync(object commandParamater)
        {
            if (!User.IsLogin)
            {
                if (_packingConfig.Token != null && !string.IsNullOrEmpty(_packingConfig.Token.AccessToken))
                {
                    _userContext.Token = _packingConfig.Token;
                }
                if (_userContext.Token != null)
                {
                    await LoginOrRegist();
                    await GetUserSummary();

                }
                else
                {
                    var loginMenu = _allMenus[CommonData.MENU_LOGIN];
                    if (loginMenu != null)
                    {
                        User.MenuCodes.Add(loginMenu);
                    }
                    Login();
                }
            }
            else
            {
                await GetUserSummary();

            }
        }
        /// <summary>
        /// 登陆
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private void Login()
        {
            SelectedMenu = _allMenus[CommonData.MENU_LOGIN];
            IsActive = true;
        }
        /// <summary>
        /// 退出
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private void Logout()
        {
            _userContext.WxAppLoginResponse = new WxAppLoginResponse();
            User = new UserViewModel();
        }
        #endregion

        #region 私有非command方法
        private static bool IsInheriteFrom(Type type, Type baseType)
        {
            if (type.BaseType == null)
            {
                return false;
            }
            if (type.BaseType == baseType)
            {
                return true;
            }
            return IsInheriteFrom(type.BaseType, baseType);
        }
        private async Task GetUserSummary()
        {
            if (_userContext.UserResponse != null && _userContext.UserResponse.EnterpriseId.HasValue)
            {
                try
                {
                    var request = new GetUserWorkSummaryRequest(_userContext.UserResponse.EnterpriseId.Value);
                    var response = await _xkmService.GetUserWorkSummaryAsync(request);
                    if (response != null)
                    {
                        Mapper.Map(response, User);
                        SelectedMenu = User.MenuCodes.Where(p => p.MenuCode == CommonData.MENU_PACKBOX).SingleOrDefault();
                        return;
                    }
                }
                catch (ApiException ex)
                {
                    MessageBox.Show($"Error: {ex.ErrorCode.GetDescription()}{ex.Message}");
                }
            }
        }
        private async Task LoginOrRegist()
        {
            var request = new LoginOrRegistRequest();
            try
            {
                var userResponse = await _xkmService.LogionOrRegistAsync(request);
                if (userResponse != null)
                {
                    if (!userResponse.EnterpriseId.HasValue)
                    {
                        MessageBox.Show("no enterprise");
                        return;
                    }
                    else if (userResponse.MenuCodes.Count == 0)
                    {
                        MessageBox.Show("no powers");
                        return;
                    }
                    _userContext.UserResponse = userResponse;
                    Mapper.Map(userResponse, User);
                    User.IsLogin = true;
                    _dispatcher.Invoke(() =>
                    {
                        var menuViews = new List<MenuViewModel>();
                        foreach (var menuCode in userResponse.MenuCodes)
                        {
                            if (_allMenus.TryGetValue(menuCode, out MenuViewModel? menuViewModel))
                            {
                                if (menuViewModel != null)
                                {
                                    menuViews.Add(menuViewModel);
                                }
                            }
                        }
                        menuViews = menuViews.OrderBy(p => p.Sort).ToList();
                        User.MenuCodes.Clear();
                        foreach (var menu in menuViews)
                        {
                            User.MenuCodes.Add(menu);
                        }
                    });
                }

                //await GetUserSummary();
            }
            catch (ApiException ex)
            {
                MessageBox.Show($"Error: {ex.ErrorCode.GetDescription()}{ex.Message}");
            }
        }


        #endregion


    }
}
